package com.weilele.mvvm.utils.`object`

import android.annotation.SuppressLint
import android.content.Context
import android.net.*
import androidx.annotation.RequiresPermission
import com.weilele.mvvm.app
import com.weilele.mvvm.utils.logI

/**
 * 描述：网络连接状态监听
 */
object NetWorkObj : ConnectivityManager.NetworkCallback() {
    private val netServer by lazy {
        (app.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).apply {
            logI { "初始化NetWorkObj 开始" }
            init(this)
            logI { "初始化NetWorkObj 完成" }
        }
    }

    /**
     * 网络是否链接
     */
    private var netWorkConnect = true


    val isNetWorkConnect: Boolean
        get() {
            return netWorkConnect
        }

    /**
     * 网络是否可用
     */
    private var netWorkAvailable = true

    val isNetWorkAvailable: Boolean
        get() {
            return netWorkAvailable
        }

    /**
     * 判断网络是否可以使用，不考虑其他情况，可用就行
     */
    val isNetworkConnectAndAvailable: Boolean
        @SuppressLint("MissingPermission")
        @RequiresPermission("android.Manifest.permission.ACCESS_NETWORK_STATE")
        get() {
            return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                val network = netServer.activeNetwork
                val info = netServer.getNetworkCapabilities(network)
                info != null && info.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
            } else {
                val info = netServer.activeNetworkInfo
                info != null && info.isAvailable
            }
        }

    /***
     * 当前链接是否wifi
     * null:没有网络链接
     * true:wifi
     * false:有链接但不是wifi
     * 注意：比如有其他连接（比如vpn连接），这里返回为false
     */
    val isWifi: Boolean?
        @SuppressLint("MissingPermission")
        @RequiresPermission("android.Manifest.permission.ACCESS_NETWORK_STATE")
        get() = checkNetwork(NetworkCapabilities.TRANSPORT_WIFI, ConnectivityManager.TYPE_WIFI)

    /***
     * 当前链接是否vpn连接
     * null:没有网络链接
     * true:VPN
     * false:没有连接vpn
     */
    val isVpn: Boolean?
        @SuppressLint("MissingPermission")
        @RequiresPermission("android.Manifest.permission.ACCESS_NETWORK_STATE")
        get() = checkNetwork(NetworkCapabilities.TRANSPORT_VPN, ConnectivityManager.TYPE_VPN)

    /**
     * 是否使用代理上网
     */
    val isWifiProxy: Boolean
        get() {
            if (isWifi != true) {
                return false
            }
            val proxyAddress = System.getProperty("http.proxyHost")
            val portStr = System.getProperty("http.proxyPort")
            return !proxyAddress.isNullOrBlank() || !portStr.isNullOrBlank()
        }

    @SuppressLint("MissingPermission")
    @RequiresPermission("android.Manifest.permission.ACCESS_NETWORK_STATE")
    private fun checkNetwork(transportType: Int, type: Int): Boolean? {
        if (!isNetWorkConnect) {
            return null
        }
        return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            val network = netServer.activeNetwork
            val info = netServer.getNetworkCapabilities(network)
            info != null && info.hasTransport(transportType)
        } else {
            val info = netServer.activeNetworkInfo
            info != null && info.isAvailable && info.type == type
        }
    }


    override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
        super.onCapabilitiesChanged(network, networkCapabilities)
        notifyListener()
    }

    override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
        super.onLinkPropertiesChanged(network, linkProperties)
        notifyListener()
    }

    override fun onLost(network: Network) {
        super.onLost(network)
        netWorkConnect = false
        notifyListener()
    }

    override fun onUnavailable() {
        super.onUnavailable()
        netWorkAvailable = false
        notifyListener()
    }

    override fun onLosing(network: Network, maxMsToLive: Int) {
        super.onLosing(network, maxMsToLive)
        notifyListener()
    }

    override fun onAvailable(network: Network) {
        super.onAvailable(network)//网络可用
        netWorkConnect = true
        netWorkAvailable = true
        notifyListener()
    }

    /**
     * 通知网络发生变化
     */
    private fun notifyListener() {
        listenerList.forEach {
            it.invoke(isNetWorkConnect, isWifi)
        }
    }

    private fun init(netServer: ConnectivityManager) {
        netServer.requestNetwork(
            NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
                .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
//            .also {//android11 会报错，展示不知道啥原因
//                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
//                    it.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
//                }
//            }
                .build(), this
        )
    }

    private val listenerList = mutableListOf<Function2<Boolean, Boolean?, Unit>>()

    /**
     * 监听网络
     */
    fun addNetChangeListener(listener: (isConnect: (Boolean), isWifi: (Boolean?)) -> Unit) {
        //初始化
        netServer
        if (!listenerList.contains(listener)) {
            listenerList.add(listener)
        }
        listener.invoke(isNetWorkConnect, isWifi)
    }

    /**
     * 移除网络监听
     */
    fun removeNetChangeListener(listener: (isConnect: (Boolean), isWifi: (Boolean?)) -> Unit) {
        listenerList.remove(listener)
    }
}